package com.tungkong.usbcamera.view;

import android.hardware.usb.UsbDevice;
import android.os.Bundle;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Surface;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.Toast;
import com.tungkong.usbcamera.R;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import com.tungkong.usbcamera.dialog.CameraDialog;
import com.serenegiant.usb.common.UVCCameraHandler;
import com.tungkong.usbcamera.UVCCameraPreview;
import com.tungkong.usbcamera.application.ClientApplication;
import com.serenegiant.usb.Size;
import com.serenegiant.usb.USBMonitor;
import com.serenegiant.usb.widget.CameraViewInterface;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class USBCameraActivity extends AppCompatActivity implements CameraDialog.CameraDialogParent, CameraViewInterface.Callback {

    private static final String TAG = "USBCameraActivity";
    public View mTextureView;
    public Toolbar mToolbar;
    public SeekBar mSeekBrightness;
    public SeekBar mSeekContrast;
    public Switch mSwitchVoice;

    private CameraViewInterface mUVCCameraView;
    private AlertDialog mDialog;

    private UVCCameraPreview mCameraHelper;

    private UsbDevice usbDevice;
    private USBMonitor.UsbControlBlock ctrlBlock;
    private UVCCameraHandler handle;

    private boolean isRequest;
    private boolean isPreview;

////   mSeekBrightness.setProgress(mCameraHelper.getModelValue(UVCCameraPreview.MODE_BRIGHTNESS));
////   mSeekContrast.setProgress(mCameraHelper.getModelValue(UVCCameraPreview.MODE_CONTRAST));


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_usbcamera);

        initView();

        // step.1 initialize UVCCameraPreview
        mUVCCameraView = (CameraViewInterface) mTextureView;
        mUVCCameraView.setCallback(this);

        mCameraHelper = UVCCameraPreview.getInstance();
        mCameraHelper.setDefaultFrameFormat(UVCCameraPreview.FRAME_FORMAT_MJPEG);
        mCameraHelper.initUSBMonitor(this);

//        mCameraHelper.addCallBack

    }

    private void initView() {

        mTextureView = this.findViewById(R.id.camera_view);
        //mTextureView.setRotation(270.0f);
        mToolbar = this.findViewById(R.id.toolbar);
        mSeekBrightness = this.findViewById(R.id.seekbar_brightness);
        mSeekContrast = this.findViewById(R.id.seekbar_contrast);
        mSwitchVoice = this.findViewById(R.id.switch_rec_voice);

        setSupportActionBar(mToolbar);

        mSeekBrightness.setVisibility(View.GONE);
        mSeekContrast.setVisibility(View.GONE);

        mSeekBrightness.setMax(100);
        mSeekBrightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
//                if(mCameraHelper != null && mCameraHelper.isCameraOpened()) {
//                    mCameraHelper.setModelValue(UVCCameraPreview.MODE_BRIGHTNESS,progress);
//                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        mSeekContrast.setMax(100);
        mSeekContrast.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
//                if(mCameraHelper != null && mCameraHelper.isCameraOpened()) {
//                    mCameraHelper.setModelValue(UVCCameraPreview.MODE_CONTRAST,progress);
//                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        // step.2 register USB event broadcast
        if (mCameraHelper != null) {
            mCameraHelper.registerUSB();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        // step.3 unregister USB event broadcast
        if (mCameraHelper != null) {
            mCameraHelper.unregisterUSB();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_toobar, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_open:
                if (mCameraHelper != null) {
                    showUSBDeviceListDialog();
                }
            case R.id.menu_close:
                if (mCameraHelper != null && mCameraHelper.isCameraOpened(usbDevice)) {
                    mCameraHelper.closeCamera(usbDevice);
                }
                break;
            case R.id.menu_preview:
                if (mCameraHelper != null && mCameraHelper.isCameraOpened(usbDevice)) {
                    mCameraHelper.startPreview(usbDevice, mUVCCameraView);
                }
                break;
            case R.id.menu_takepic:
                if (mCameraHelper == null || !mCameraHelper.isCameraOpened(usbDevice)) {
                    showShortMsg("sorry,camera open failed");
                    return super.onOptionsItemSelected(item);
                }
                String picPath = UVCCameraPreview.ROOT_PATH + ClientApplication.DIRECTORY_NAME + File.separator + System.currentTimeMillis() + UVCCameraPreview.SUFFIX_JPEG;
                // 截图预览图数据
                mCameraHelper.capturePicture(usbDevice,picPath);
                break;
            case R.id.menu_cutpic:
                if (mCameraHelper == null || !mCameraHelper.isCameraOpened(usbDevice)) {
                    showShortMsg("sorry,camera open failed");
                    return super.onOptionsItemSelected(item);
                }
                String cutPath = UVCCameraPreview.ROOT_PATH + ClientApplication.DIRECTORY_NAME + File.separator + System.currentTimeMillis() + UVCCameraPreview.SUFFIX_JPEG;
                // 截图摄像头数据
                mCameraHelper.captureCut(usbDevice,cutPath);
                break;
            case R.id.menu_recording:
                if (mCameraHelper == null || !mCameraHelper.isCameraOpened(usbDevice)) {
                    showShortMsg("sorry,camera open failed");
                    return super.onOptionsItemSelected(item);
                }
                if (!mCameraHelper.isPushing(usbDevice)) {
                    String videoPath = UVCCameraPreview.ROOT_PATH + ClientApplication.DIRECTORY_NAME + File.separator + System.currentTimeMillis() + UVCCameraPreview.SUFFIX_MP4;
                    mCameraHelper.startPusher(usbDevice);
                    // if you only want to push stream,please call like this
                    // mCameraHelper.startPusher(listener);
                    showShortMsg("start record...");
                    mSwitchVoice.setEnabled(false);
                } else {
                    mCameraHelper.stopPusher(usbDevice);
                    showShortMsg("stop record...");
                    mSwitchVoice.setEnabled(true);
                }
                break;
            case R.id.menu_resolution:
                if (mCameraHelper == null || !mCameraHelper.isCameraOpened(usbDevice)) {
                    showShortMsg("sorry,camera open failed");
                    return super.onOptionsItemSelected(item);
                }
                showResolutionListDialog();
                break;
            case R.id.menu_focus:
                if (mCameraHelper == null || !mCameraHelper.isCameraOpened(usbDevice)) {
                    showShortMsg("sorry,camera open failed");
                    return super.onOptionsItemSelected(item);
                }
                mCameraHelper.startCameraFoucs(usbDevice);
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    private void showResolutionListDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(USBCameraActivity.this);
        View rootView = LayoutInflater.from(USBCameraActivity.this).inflate(R.layout.layout_dialog_list, null);
        ListView listView = (ListView) rootView.findViewById(R.id.listview_dialog);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(USBCameraActivity.this, android.R.layout.simple_list_item_1, getResolutionList());
        if (adapter != null) {
            listView.setAdapter(adapter);
        }
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                if (mCameraHelper == null || !mCameraHelper.isCameraOpened(usbDevice))
                    return;
                final String resolution = (String) adapterView.getItemAtPosition(position);
                String[] tmp = resolution.split("x");
                if (tmp != null && tmp.length >= 2) {
                    int widht = Integer.valueOf(tmp[0]);
                    int height = Integer.valueOf(tmp[1]);
                    mCameraHelper.setPreviewSize(usbDevice,widht, height);
                }
                mDialog.dismiss();
            }
        });

        builder.setView(rootView);
        mDialog = builder.create();
        mDialog.show();
    }

    private void showUSBDeviceListDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(USBCameraActivity.this);
        View rootView = LayoutInflater.from(USBCameraActivity.this).inflate(R.layout.layout_dialog_list, null);
        ListView listView = (ListView) rootView.findViewById(R.id.listview_dialog);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(USBCameraActivity.this, android.R.layout.simple_list_item_1, getUsbDevices());
        if (adapter != null) {
            listView.setAdapter(adapter);
        }
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {

                usbDevice = mCameraHelper.getConnectedUsbDevices().get(position);
                mCameraHelper.openCamera(usbDevice,mUVCCameraView);
                mDialog.dismiss();

            }
        });

        builder.setView(rootView);
        mDialog = builder.create();
        mDialog.show();
    }

    // example: {640x480,320x240,etc}
    private List<String> getResolutionList() {
        List<Size> list = mCameraHelper.getSupportedPreviewSizes(usbDevice);
        List<String> resolutions = null;
        if (list != null && list.size() != 0) {
            resolutions = new ArrayList<>();
            for (Size size : list) {
                if (size != null) {
                    resolutions.add(size.width + "x" + size.height);
                }
            }
        }
        return resolutions;
    }

    private List<String> getUsbDevices() {
        List<String> usbs = new ArrayList<>();
        String key = null;
        for (UsbDevice device: mCameraHelper.getConnectedUsbDevices()) {
            key = "(vid:"+ device.getVendorId() + ",pid:" +device.getProductId() + "),name:" + device.getDeviceName();
            usbs.add(key);
        }
        return usbs;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // step.4 release uvc camera resources
        if (mCameraHelper != null) {
            mCameraHelper.release(usbDevice);
        }
    }

    private void showShortMsg(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }

    @Override
    public USBMonitor getUSBMonitor() {
        return mCameraHelper.getUSBMonitor();
    }

    @Override
    public void onDialogResult(boolean canceled) {
        if (canceled) {
            showShortMsg("取消操作");
        }
    }

    @Override
    public void onSurfaceCreated(CameraViewInterface view, Surface surface) {
        Log.e("onSurfaceCreated","onSurfaceCreated");
    }

    @Override
    public void onSurfaceChanged(CameraViewInterface view, Surface surface, int width, int height) {
        Log.e("onSurfaceChanged","onSurfaceChanged");
    }

    @Override
    public void onSurfaceDestroy(CameraViewInterface view, Surface surface) {
        Log.e("onSurfaceDestroy","onSurfaceDestroy");
        if (isPreview && mCameraHelper.isCameraOpened(usbDevice)) {
            mCameraHelper.stopPreview(usbDevice);
            isPreview = false;
        }
    }

}
